package ru.nosport.matrixaria;

import java.io.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * User: Victor Fabrichenko
 * Date: 15.12.2008
 * Time: 18:12:02
 */
public class LinuxMatrixariaService implements Runnable {
	private volatile boolean stop = false;

	static private final String cmdStart = "start";
	static private final String cmdStop = "stop";

	private ExecutorService exec;
	private MatrixariaMain mm;
	private String srvPipeName;

	static class Pipe {

		/**
		 *
		 * @param _pipeName - 
		 */
		static void createPipe(String _pipeName){
			try {
				Runtime.getRuntime().exec("mkfifo "+_pipeName);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 *
		 * @param _pipeName -
		 */
		static void removePipe(String _pipeName){
			try {
				Runtime.getRuntime().exec("rm "+_pipeName);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}


		/**
		 *
		 * @param _pipeName -
		 * @param _mess -
		 */
		static void send(String _pipeName, String _mess) {
			BufferedWriter pipeWriter = null;
			try {
				pipeWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(_pipeName)));
				pipeWriter.write(_mess);
				pipeWriter.flush();
				pipeWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (pipeWriter != null){
					try {
						pipeWriter.close();
					} catch (IOException ignore) {}
				}
			}
		}

		/**
		 *
		 * @param _pipeName -
		 * @return - 
		 */
		static String read(String _pipeName) {
			String line = null;
			BufferedReader read = null;

			try {
				read = new BufferedReader(new FileReader(_pipeName));
				line = read.readLine();
				read.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (read != null){
						read.close();
					}
				}catch(IOException ignore) {}
			}

			return line;
		}
	}

	public static void main(String[] _args) {
		if (_args.length < 3) {
			System.out.println("Error!");
			System.exit(1);
		}
		System.out.println("----------------");

		String cmd = _args[0].toLowerCase();
		String path = _args[1];
		String pipeName = _args[2];

		System.out.println("main args: "+cmd);
		System.out.println("main args: "+path);
		System.out.println("main args: "+pipeName);

		if(_args.length == 3 && cmd.equals(cmdStart)) {
			LinuxMatrixariaService service = new LinuxMatrixariaService(path, pipeName);
			service.start();
		} else {
			Pipe.send(pipeName, cmd);
		}
	}

	/**
	 *
	 * @param _path -
	 * @param _pipeName -
	 */
	protected LinuxMatrixariaService(String _path, String _pipeName) {
		MatrixariaMain.initialize(_path);
		this.mm = MatrixariaMain.getInstance();
		this.srvPipeName = _pipeName;
	}

	/**
	 *
	 */
	protected void start(){
		System.out.println("Start: "+this.hashCode());
		Pipe.createPipe(this.srvPipeName);
		this.mm.startServer();
		this.exec = Executors.newSingleThreadExecutor();
		this.exec.execute(this);
	}

	/**
	 *
	 */
	protected void stop(){
		System.out.println("Stop: "+this.hashCode());
		this.mm.shutdownServer();
		Pipe.removePipe(this.srvPipeName);
		this.stop = true;
		this.exec.shutdownNow();
		try {
			this.exec.awaitTermination(1000, TimeUnit.MILLISECONDS);
		} catch (InterruptedException ignore) {}
	}

	/**
	 *
	 */
	@Override
	public void run() {
		while(!this.stop){
			String cmd = Pipe.read(this.srvPipeName).toLowerCase();
			if(cmd.equals(cmdStop)){
				this.stop();
			}
		}
	}

}

